package repository

import (
	"django_blog_gin/internal/model"
	"django_blog_gin/internal/svc"
	"django_blog_gin/internal/ws"
	"encoding/json"
	"fmt"
	"strconv"
	"time"
)

// ChatRepository 聊天存储库
type ChatRepository struct {
	svcCtx *svc.ServiceContext
}

// NewChatRepository 创建新的聊天存储库
func NewChatRepository(svcCtx *svc.ServiceContext) *ChatRepository {
	r := &ChatRepository{
		svcCtx: svcCtx,
	}
	r.svcCtx.WSManager.SetMessageHandler(r.MessageHandler)
	r.svcCtx.WSManager.SetHistoryHandler(r.GetMessages)
	r.svcCtx.WSManager.SetSearchDateHandler(r.SearchMessagesWithDate)
	return r
}

// 创建聊天存储库
// chatRepo := repository.NewChatRepository(&ServiceContext{
// 	MysqlDb: MysqlDbConn,
// })

// 配置消息处理函数，用于保存消息到数据库
func (r *ChatRepository) MessageHandler(message []byte, client *ws.Client) error {
	var msg ws.Message
	if err := json.Unmarshal(message, &msg); err != nil {
		return err
	}

	// 从client.ID解析用户ID
	userID, err := strconv.Atoi(client.ID)
	if err != nil {
		return fmt.Errorf("invalid user ID: %s", client.ID)
	}

	// 保存消息到数据库
	return r.SaveMessage(&msg, userID, client.Username)
}

// SaveMessage 保存消息到数据库
func (r *ChatRepository) SaveMessage(msg *ws.Message, userId int, userName string) error {
	chatMessageModel := model.ChatMessage{}
	query := fmt.Sprintf(`
        INSERT INTO %s (sender_id, sender_name, message_type, content, file_path, file_name, file_size, file_mime, created_at)
        VALUES (:sender_id, :sender_name, :message_type, :content, :file_path, :file_name, :file_size, :file_mime, :created_at)
	`, chatMessageModel.TableName())
	// query := `
	// INSERT INTO chat_messages (sender_id, sender_name, message_type, content, file_path, file_name, file_size, file_mime)
	// VALUES (:sender_id, :sender_name, :message_type, :content, :file_path, :file_name, :file_size, :file_mime)
	// `
	chatMessageModel.SenderId = userId
	chatMessageModel.SenderName = userName
	chatMessageModel.MessageType = msg.Type
	chatMessageModel.Content = msg.Content
	chatMessageModel.CreatedAt = time.Unix(msg.Timestamp/1000, 0).Local()
	if msg.FileInfo != nil {
		chatMessageModel.FilePath = msg.FileInfo.URL
		chatMessageModel.FileName = msg.FileInfo.Name
		chatMessageModel.FileSize = msg.FileInfo.Size
		chatMessageModel.FileMime = msg.FileInfo.Type
	}

	// params := map[string]interface{}{
	// 	"sender_id":    userId,
	// 	"sender_name":  userName,
	// 	"message_type": msg.Type,
	// 	"content":      msg.Content,
	// }

	// // 如果有文件信息，添加到参数中
	// if msg.FileInfo != nil {
	// 	params["file_path"] = msg.FileInfo.URL
	// 	params["file_name"] = msg.FileInfo.Name
	// 	params["file_size"] = msg.FileInfo.Size
	// 	params["file_mime"] = msg.FileInfo.Type
	// }

	// 执行插入
	_, err := r.svcCtx.MysqlDb.NamedExec(query, chatMessageModel)
	if err != nil {
		return fmt.Errorf("保存消息失败: %v", err)
	}

	// 获取插入的ID
	var messageId int
	err = r.svcCtx.MysqlDb.QueryRow("SELECT LAST_INSERT_ID()").Scan(&messageId)
	if err != nil {
		return err
	}
	// id, err := result.LastInsertId()
	// if err != nil {
	// return fmt.Errorf("获取消息ID失败: %v", err)
	// }

	return nil
}

// GetMessages 获取消息列表（分页）
func (r *ChatRepository) GetMessages(offset, limit int) ([]ws.Message, error) {
	charMessageModel := model.ChatMessage{}
	query := fmt.Sprintf(`
        SELECT id, sender_id, sender_name, message_type, content, file_path, file_name, file_size, file_mime, created_at
        FROM %s
        ORDER BY created_at DESC
        LIMIT %d OFFSET %d
    `, charMessageModel.TableName(), limit, offset)

	charMessages := make([]model.ChatMessage, 0)
	err := r.svcCtx.MysqlDb.Select(&charMessages, query)
	if err != nil {
		return nil, fmt.Errorf("获取消息失败: %v", err)
	}
	// defer rows.Close()

	messages := make([]ws.Message, 0)
	for _, charMessage := range charMessages {
		message := &ws.Message{
			Sender:    charMessage.SenderName,
			Content:   charMessage.Content,
			Type:      charMessage.MessageType,
			Timestamp: charMessage.CreatedAt.Unix() * 1000,
		}

		if charMessage.FilePath != "" {
			message.FileInfo = &ws.FileInfo{
				Name: charMessage.FileName,
				Size: charMessage.FileSize,
				Type: charMessage.FileMime,
				URL:  charMessage.FilePath,
			}
		}

		messages = append(messages, *message)
	}

	return messages, nil
}

// 根据日期搜索消息
func (r *ChatRepository) SearchMessagesWithDate(searchDate string, offset, limit int) ([]ws.Message, error) {
	// 假如用户输入2025 09 26 日期的查询， 我就要获取到2025 09 26 00:00:00 到 2025 09 26 23:59:59 的消息
	charMessageModel := model.ChatMessage{}

	// 将传入的毫秒级时间戳转换为time.Time对象
	inputTime, err := time.Parse("2006-01-02", searchDate)
	// inputTime, err := time.Parse(time.RFC3339, searchDate)
	if err != nil {
		return nil, fmt.Errorf("无效的日期格式: %v", err)
	}

	// 计算当天的开始时间（00:00:00）
	startOfDay := time.Date(inputTime.Year(), inputTime.Month(), inputTime.Day(), 0, 0, 0, 0, inputTime.Location()).Format("2006-01-02 15:04:05")
	// 计算当天的结束时间（23:59:59）
	endOfDay := time.Date(inputTime.Year(), inputTime.Month(), inputTime.Day(), 23, 59, 59, 999999999, inputTime.Location()).Format("2006-01-02 15:04:05")

	query := fmt.Sprintf(`
        SELECT id, sender_id, sender_name, message_type, content, file_path, file_name, file_size, file_mime, created_at
        FROM %s
        WHERE created_at >= ? AND created_at <= ? 
        ORDER BY created_at DESC
        LIMIT %d OFFSET %d
    `, charMessageModel.TableName(), limit, offset)

	charMessages := make([]model.ChatMessage, 0)
	err = r.svcCtx.MysqlDb.Select(&charMessages, query, startOfDay, endOfDay)
	if err != nil {
		return nil, fmt.Errorf("获取消息失败: %v", err)
	}

	messages := make([]ws.Message, 0)
	for _, charMessage := range charMessages {
		message := &ws.Message{
			Sender:    charMessage.SenderName,
			Content:   charMessage.Content,
			Type:      charMessage.MessageType,
			Timestamp: charMessage.CreatedAt.Unix() * 1000,
		}

		if charMessage.FilePath != "" {
			message.FileInfo = &ws.FileInfo{
				Name: charMessage.FileName,
				Size: charMessage.FileSize,
				Type: charMessage.FileMime,
				URL:  charMessage.FilePath,
			}
		}

		messages = append(messages, *message)
	}

	return messages, nil
}

// 根据文件类型搜索消息
func (r *ChatRepository) SearchMessagesWithFileType(fileType string, offset, limit int) ([]ws.Message, error) {
	// 文件类型暂时只取分两种， 一个是图片， 一个是文件
	// 图片的mime类型是 image/*
	// 文件的mime类型是 application/*
	charMessageModel := model.ChatMessage{}

	query := fmt.Sprintf(`
        SELECT id, sender_id, sender_name, message_type, content, file_path, file_name, file_size, file_mime, created_at
        FROM %s
        WHERE file_mime LIKE ?
        ORDER BY created_at DESC
        LIMIT %d OFFSET %d
    `, charMessageModel.TableName(), limit, offset)

	charMessages := make([]model.ChatMessage, 0)
	err := r.svcCtx.MysqlDb.Select(&charMessages, query, fileType+"%")
	if err != nil {
		return nil, fmt.Errorf("获取消息失败: %v", err)
	}

	messages := make([]ws.Message, 0)
	for _, charMessage := range charMessages {
		message := &ws.Message{
			Sender:    charMessage.SenderName,
			Content:   charMessage.Content,
			Type:      charMessage.MessageType,
			Timestamp: charMessage.CreatedAt.Unix() * 1000,
		}

		if charMessage.FilePath != "" {
			message.FileInfo = &ws.FileInfo{
				Name: charMessage.FileName,
				Size: charMessage.FileSize,
				Type: charMessage.FileMime,
				URL:  charMessage.FilePath,
			}
		}

		messages = append(messages, *message)
	}

	return messages, nil
}

// SearchMessages 搜索消息
func (r *ChatRepository) SearchMessages(keyword string, offset, limit int) ([]*ws.Message, error) {
	query := `
        SELECT id, sender_id, sender_name, message_type, content, file_path, file_name, file_size, file_mime, created_at
        FROM chat_messages
        WHERE content LIKE :keyword OR file_name LIKE :keyword
        ORDER BY created_at DESC
        LIMIT :limit OFFSET :offset
    `

	params := map[string]interface{}{
		"keyword": fmt.Sprintf("%%%s%%", keyword),
		"limit":   limit,
		"offset":  offset,
	}

	rows, err := r.svcCtx.MysqlDb.NamedQuery(query, params)
	if err != nil {
		return nil, fmt.Errorf("搜索消息失败: %v", err)
	}
	defer rows.Close()

	// 以下代码与GetMessages相同，用于处理结果集
	messages := make([]*ws.Message, 0)
	// 具体实现略...

	return messages, nil
}
